package com.glintt.sinnerg.web.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.glintt.sinnerg.web.dto.LoginInfo;
import com.glintt.sinnerg.web.dto.Person;
import com.glintt.sinnerg.web.service.LdapService;

@Controller
public class AppController {

    private static final String COOKIE_ID = "LOGIN_ID";

    @Autowired
    private LdapService service;

    private final Map<String, LoginInfo> loginMap = new HashMap<>();

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public void login(@RequestBody LoginInfo loginInfo, HttpServletResponse response) {

        System.out.println(loginInfo.toString());

        Person person = authenticate(loginInfo);
        if (person != null) {
            loginInfo.setPerson(person);
            String username = loginInfo.getUsername();
            Cookie cookie = new Cookie(COOKIE_ID, username);
            cookie.setSecure(true);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
            response.setStatus(HttpServletResponse.SC_OK);
            this.loginMap.put(username, loginInfo);
        } else {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }

    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        Cookie cookieKiller = findLoginIdCookie(request);
        if (cookieKiller != null) {
            cookieKiller.setMaxAge(0);
            response.addCookie(cookieKiller);
            loginMap.remove(cookieKiller.getValue());
        }
    }

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public @ResponseBody
    List<Person> search(@RequestParam String query, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LoginInfo loginInfo = findLoginInfo(request);
        if (loginInfo != null) {
            return service.search(loginInfo.getUsername(), loginInfo.getPassword(), query);
        } else {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return null;
        }
    }

    private Cookie findLoginIdCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (COOKIE_ID.equals(cookie.getName())) {
                    return cookie;
                }
            }
        }
        return null;
    }

    private LoginInfo findLoginInfo(HttpServletRequest request) {
        Cookie cookie = findLoginIdCookie(request);
        if (cookie != null) {
            return loginMap.get(cookie.getValue());
        }
        return null;
    }

    private Person authenticate(LoginInfo loginInfo) {
        String username = loginInfo.getUsername();
        String password = loginInfo.getPassword();

        if (("teste").equals(loginInfo.getUsername())) {
            Person dummy = new Person();
            dummy.setName("teste");
            dummy.setEmail("test@mail.pt");
            return dummy;
        }

        try {
            return service.authenticate(username, password);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @RequestMapping(value = "/ping", method = RequestMethod.GET)
    public @ResponseBody
    String login() {
        return "pong";
    }
}
